package controllers;

import helpers.ValidateHelper;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.TreeMap;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import models.DealModel;
import models.OrderModel;
import models.OrderProductModel;
import models.ProductModel;
import models.UserModel;
import admin.data.DealData;
import admin.data.ProductData;
import data.GeoData;
import data.OrderData;

@SuppressWarnings("serial")
public class PaymentServlet extends HttpServlet {

	private static final Logger log = Logger.getLogger(PaymentServlet.class
			.getName());

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws IOException, ServletException {
		try {
			response.setCharacterEncoding("UTF-8");
			String[] splitted = request.getRequestURI().split("/");
			HttpSession session = request.getSession();
			if (splitted.length > 2) {
				String action = splitted[2];
				String id = "";
				OrderModel order = (OrderModel) session
						.getAttribute("user_order");
				if (action.equals("thong-tin-thanh-toan")) {
					// kiểm tra cho phép quay lại bước này khi order step đã lớn
					// hơn 1.
					if (order != null && order.getOrderStep() >= 1) {
						if (order.getOrderStep() == 1) {
							UserModel user = (UserModel) session
									.getAttribute("user_logged_in");
							// nếu mới đến bước này mà người dùng đăng nhập và
							// redirect lại thì lấy thông tin người dùng đưa vào
							// order.
							if (user != null && user.getUsername().length() > 0) {
								order.setUsername(user.getUsername());
								order.setShipName(user.getName());
								order.setShipMail(user.getUsername());
								order.setShipPhoneNumber(user.getPhone());
								order.setShipType(1);
								StringBuilder fullAddress = new StringBuilder();
								if (user.getAddress() != null
										&& user.getAddress().length() > 0) {
									fullAddress.append(user.getAddress());
								}
								if (user.getStreet() != null
										&& user.getStreet().length() > 0) {
									fullAddress.append(", ");
									fullAddress.append(user.getStreet());
								}
								order.setShipAddress(fullAddress.toString());
								order.setShipCity(user.getCity());
								order.setShipDistrict(user.getDistrict());
								order.setShipWard(user.getWard());
								order.setUsername(user.getUsername());
							}
						}
						session.setAttribute("user_order", order);
						request.getRequestDispatcher("/pages/payment1.jsp")
								.forward(request, response);
					} else {
						request.setAttribute(
								"sms",
								"Giỏ hàng của bạn không có sản phẩm nào hoặc session đã hết hạn để thực hiện thao tác này.");
						request.getRequestDispatcher("/pages/no_cart.jsp")
								.forward(request, response);
					}

				} else if (action.equals("hinh-thuc-thanh-toan")) {
					if (order != null && order.getOrderStep() >= 2) {
						session.setAttribute("user_order", order);
						request.getRequestDispatcher("/pages/payment2.jsp")
								.forward(request, response);
					} else {
						request.setAttribute(
								"sms",
								"Giỏ hàng của bạn không có sản phẩm nào hoặc session đã hết hạn để thực hiện thao tác này.");
						request.getRequestDispatcher("/pages/no_cart.jsp")
								.forward(request, response);
					}
				} else if (action.equals("xac-nhan-don-hang")) {
					if (order != null && order.getOrderStep() >= 3) {
						session.setAttribute("user_order", order);
						request.getRequestDispatcher("/pages/payment3.jsp")
								.forward(request, response);
					} else {
						request.setAttribute(
								"sms",
								"Giỏ hàng của bạn không có sản phẩm nào hoặc session đã hết hạn để thực hiện thao tác này.");
						request.getRequestDispatcher("/pages/no_cart.jsp")
								.forward(request, response);
					}
				} else if (action.equals("dat-hang-thanh-cong")) {
					if (order != null && order.getOrderStep() >= 4) {
						// đặt hàng thành công, xóa order khỏi session, đưa ra
						// thông báo cho người dùng.
						session.removeAttribute("user_order");
						request.setAttribute("user_order", order);
						request.getRequestDispatcher(
								"/pages/payment_success.jsp").forward(request,
								response);
					} else {
						request.setAttribute(
								"sms",
								"Giỏ hàng của bạn không có sản phẩm nào hoặc session đã hết hạn để thực hiện thao tác này.");
						request.getRequestDispatcher("/pages/no_cart.jsp")
								.forward(request, response);
					}
				} else {
					// khi click vào link mua hàng. Lấy thông tin deal, tạo
					// order gắn vào session rồi đưa về trang thông tin thanh
					// toán.
					id = splitted[2];
					DealModel deal = DealData.getById(id);
					if (deal != null
							&& deal.getEndTime().compareTo(
									Calendar.getInstance().getTime()) > 0
							&& deal.getStatus() == 2
							&& deal.getAmount() != deal.getLimit()) {
						List<ProductModel> listProduct = ProductData
								.getByDealId(deal.getDealId());
						List<OrderProductModel> listOrderProduct = new ArrayList<OrderProductModel>();
						if (listProduct != null && listProduct.size() > 0) {
							for (ProductModel productModel : listProduct) {
								OrderProductModel oP = new OrderProductModel();
								oP.setName(productModel.getName());
								oP.setProductId(productModel.getProductId());
								oP.setQuantity(0);
								listOrderProduct.add(oP);
							}
						}
						order = new OrderModel();
						listOrderProduct.get(0).setQuantity(1);
						order.setListOrderProductObject(listOrderProduct);
						order.setUnitPrice(deal.getPriceDiscount());
						order.setDeal(deal);
						order.setDealId(deal.getDealId());
						order.setDealName(deal.getName());
						order.setDealProductType(deal.getProductType());
						order.setDealShortName(deal.getShortName());
						order.setSalername(deal.getUsername());
						UserModel user = (UserModel) session
								.getAttribute("user_logged_in");
						if (user != null && user.getUsername().length() > 0) {
							order.setUsername(user.getUsername());
							order.setShipName(user.getName());
							order.setShipMail(user.getUsername());
							order.setShipPhoneNumber(user.getPhone());
							order.setShipType(1);
							StringBuilder fullAddress = new StringBuilder();
							if (user.getAddress() != null
									&& user.getAddress().length() > 0) {
								fullAddress.append(user.getAddress());
							}
							if (user.getStreet() != null
									&& user.getStreet().length() > 0) {
								fullAddress.append(", ");
								fullAddress.append(user.getStreet());
							}
							order.setShipAddress(fullAddress.toString());
							order.setShipCity(user.getCity());
							order.setShipDistrict(user.getDistrict());
							order.setShipWard(user.getWard());
							order.setUsername(user.getUsername());
						}
						order.setOrderStep(1);
						session.setAttribute("user_order", order);
						response.sendRedirect("/dang-ky-mua-hang/thong-tin-thanh-toan");
					} else {
						System.out
								.println("Deal không tồn tại hoặc đã hết hạn mua !");
						request.getRequestDispatcher("/pages/error.jsp")
								.forward(request, response);
					}
				}
			} else {
				request.getRequestDispatcher("/pages/error.jsp").forward(
						request, response);
			}
		} catch (Exception e) {
			log.warning(e.toString());
			e.printStackTrace();
			request.getRequestDispatcher("/pages/error.jsp").forward(request,
					response);
		}
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		try {
			HttpSession session = req.getSession();
			OrderModel order = (OrderModel) session.getAttribute("user_order");
			if (order != null) {
				String action = req.getParameter("action");
				if (action != null && action.equals("thong-tin-thanh-toan")) {
					order.setOrderStep(2);
					// xử lý lấy thông tin thanh toán.
					processPaymentInfor(req, resp, session, order);
				} else if (action != null
						&& action.equals("hinh-thuc-thanh-toan")) {
					processOrderProduct(req, resp, order);
					String paymentType = req.getParameter("paymentType");
					if (paymentType != null && paymentType.equals("2")) {
						order.setPaymentType(2);
					} else {
						order.setPaymentType(1);
					}
					order.setOrderStep(3);
					session.setAttribute("user_order", order);
					// và redirect sang trang xác nhận.
					resp.sendRedirect("/dang-ky-mua-hang/xac-nhan-don-hang");
				} else if (action != null && action.equals("xac-nhan-don-hang")) {
					UserModel user = (UserModel) session
							.getAttribute("user_logged_in");
					if (user != null && user.getUsername().length() > 0) {
						order.setOrderStep(4);
						processOrderProduct(req, resp, order);
						int totalQuantity = 0;
						order.setOrderId(OrderData.getOrderRandomId(order
								.getDealId()));
						List<String> listProduct = new ArrayList<String>();
						for (OrderProductModel product : order
								.getListOrderProductObject()) {
							ProductModel p = ProductData.getById(product
									.getProductId());
							if (p != null) {
								p.setTotalOrderQuantity(product.getQuantity()
										+ p.getTotalOrderQuantity());
								ProductData.insert(p);
								if (product.getQuantity() != 0) {
									listProduct.add(product.toString());
								}
							}
							totalQuantity += product.getQuantity();
						}
						// check nếu order quá số lượng giới hạn của Deal thì
						// thông báo cho người dùng yêu cầu order số lượng nhỏ
						// hơn.
						DealModel deal = DealData.getById(order.getDealId());
						if (deal != null) {
							int remain = deal.getLimit() - deal.getAmount();
							if (totalQuantity > remain) {
								session.setAttribute(
										"success",
										"Số lượng sản phẩm trong kho không đủ cho đơn hàng của bạn. Vui lòng chọn lại sản phẩm với số lượng nhỏ hơn hoặc bằng "
												+ remain);
								session.setAttribute("user_order", order);
								resp.sendRedirect("/dang-ky-mua-hang/xac-nhan-don-hang");
								return;
							}
						}
						order.setQuantity(totalQuantity);
						order.setTotalPrice(totalQuantity
								* order.getUnitPrice());
						order.setListOrderProduct(listProduct);
						order.setUsername(user.getUsername());
						order.setStatus(1);
						if (session.getAttribute("email_redirect") != null) {
							try {
								boolean booSession = (Boolean) session
										.getAttribute("email_redirect");
								if (booSession) {
									order.setFromEmail(1);
								} else {
									order.setFromEmail(0);
								}
							} catch (Exception e) {
								order.setFromEmail(0);
							}
						}
						deal.setUserAmount(deal.getUserAmount() + 1);
						deal.setAmount(deal.getAmount() + totalQuantity);
						if (deal.getAmount() >= deal.getLimit()) {
							deal.setStatus(3);
						}
						DealData.insert(deal);
						OrderData.insert(order);
						session.setAttribute("user_order", order);
						resp.sendRedirect("/dang-ky-mua-hang/dat-hang-thanh-cong");
					} else {
						resp.sendRedirect("/dang-ky-mua-hang/xac-nhan-don-hang");
					}
				}
			} else {

			}
		} catch (Exception e) {
			log.warning(e.toString());
			e.printStackTrace();
			req.getRequestDispatcher("/pages/error.jsp").forward(req, resp);
		}
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	protected void processPaymentInfor(HttpServletRequest req,
			HttpServletResponse resp, HttpSession session, OrderModel order)
			throws ServletException, IOException {
		TreeMap check = new TreeMap();
		String type = req.getParameter("type");
		if (type != null && type.equals("1")) {
			DealModel deal = DealData.getById(order.getDealId());
			// nếu là thanh toán tại nhà.
			String shipName = req.getParameter("shipName");
			String shipMail = req.getParameter("shipMail");
			String shipPhoneNumber = req.getParameter("shipPhoneNumber");
			String shipAddressType = req.getParameter("shipAddressType");
			String shipAddress = req.getParameter("shipAddress");
			String city = req.getParameter("city");
			String district = req.getParameter("district");
			String ward = req.getParameter("ward");
			String note = req.getParameter("note");

			if (shipName != null && !shipName.isEmpty()) {
				order.setShipName(shipName);
			} else {
				order.setShipName(shipName);
				check.put("shipName", "Họ tên không được để trống.");
			}
			if (shipMail != null && !shipMail.isEmpty()
					&& ValidateHelper.isEmail(shipMail)) {
				order.setShipMail(shipMail);
			} else {
				order.setShipMail(shipMail);
				check.put("shipMail",
						"Email không hợp lệ. (Ví dụ : abcd@gmail.com)");
			}
			if (shipPhoneNumber != null && !shipPhoneNumber.isEmpty()
					&& ValidateHelper.isPhoneNumber(shipPhoneNumber)) {
				order.setShipPhoneNumber(shipPhoneNumber);
			} else {
				order.setShipPhoneNumber(shipPhoneNumber);
				check.put("shipPhoneNumber",
						"Số điện thoại không hợp lệ (chỉ chấp nhận 09xxxxxxxx, 01xxxxxxxxx)");
			}
			if (shipAddressType != null && !shipAddressType.isEmpty()) {
				if (shipAddressType.equals("1")) {
					order.setShipAddressType(1);
				} else {
					order.setShipAddressType(2);
				}

			} else {
				check.put("shipAddressType", "Cần chọn nơi giao nhận hàng.");
			}
			if (shipAddress != null && !shipAddress.isEmpty()) {
				order.setShipAddress(shipAddress);
			} else {
				order.setShipAddress(shipAddress);
				check.put("shipAddress", "Địa chỉ không được bỏ trống.");
			}
			if (city != null && !city.isEmpty()) {
				if (city.equals(deal.getCity())) {
					order.setShipCity(city);
				} else {
					check.put("city",
							"Deal hiện tại không được cung cấp tại thành phố này.");
				}
			} else {
				check.put("city", "Cần chọn thành phố.");
			}
			if (district != null && !district.isEmpty()) {
				order.setShipDistrict(district);
			} else {
				check.put("district", "Cần chọn quận huyện.");
			}
			if (ward != null && !ward.isEmpty()) {
				order.setShipWard(ward);
			} else {
				check.put("ward", "Cần chọn phường xã.");
			}
			if (note != null && !note.isEmpty()) {
				order.setNote(note);
			}
			order.setShipType(1);
		} else if (type != null && type.equals("2")) {
			// nếu là thanh toán tại cùng mua.
			String shipName = req.getParameter("shipName1");
			String shipMail = req.getParameter("shipMail1");
			String shipPhoneNumber = req.getParameter("shipPhoneNumber1");
			String note = req.getParameter("note1");

			if (shipName != null && !shipName.isEmpty()) {
				order.setShipName(shipName);
			} else {
				order.setShipName(shipName);
				check.put("shipName1", "Họ tên không được để trống.");
			}
			if (shipMail != null && !shipMail.isEmpty()
					&& ValidateHelper.isEmail(shipMail)) {
				order.setShipMail(shipMail);
			} else {
				order.setShipMail(shipMail);
				check.put("shipMail1",
						"Email không hợp lệ. (Ví dụ : abcd@gmail.com)");
			}
			if (shipPhoneNumber != null && !shipPhoneNumber.isEmpty()) {
				order.setShipPhoneNumber(shipPhoneNumber);
			} else {
				order.setShipPhoneNumber(shipPhoneNumber);
				check.put("shipPhoneNumber1",
						"Số điện thoại không hợp lệ (chỉ chấp nhận 09xxxxxxxx, 01xxxxxxxxx)");
			}
			if (note != null && !note.isEmpty()) {
				order.setNote(note);
			}
			order.setShipType(2);
		}
		// gán thông tin chọn sản phẩm của deal vào order.
		processOrderProduct(req, resp, order);
		// nếu là thanh toán tại nhà thì lưu thông tin full address vào order.
		if (order.getShipType() == 1) {
			GeoData geoData = new GeoData();
			StringBuilder temStr = new StringBuilder();
			if (order.getShipFloor() != null && !order.getShipFloor().isEmpty()) {
				temStr.append("Tầng " + order.getShipFloor() + ", ");
			}
			if (order.getShipAddress() != null
					&& !order.getShipAddress().isEmpty()) {
				temStr.append(order.getShipAddress() + ", ");
			}
			if (order.getShipStreet() != null
					&& !order.getShipStreet().isEmpty()) {
				temStr.append(order.getShipStreet() + ", ");
			}
			if (order.getShipWard() != null && !order.getShipWard().isEmpty()) {
				temStr.append(geoData.getGeo(order.getShipWard()).getName()
						+ ", ");
			}
			if (order.getShipDistrict() != null
					&& !order.getShipDistrict().isEmpty()) {
				temStr.append(geoData.getGeo(order.getShipDistrict()).getName()
						+ ", ");
			}
			if (order.getShipCity() != null && !order.getShipCity().isEmpty()) {
				temStr.append(geoData.getGeo(order.getShipCity()).getName());
			}
			order.setShipAddressFull(temStr.toString());
		} else {
			order.setShipAddressFull("Nhận hàng tại onsale365.com.vn - Số 46 D2 Khu đô thị mới Đại Kim, Phường Đại Kim, Quận Hoàng Mai, Hà Nội");
		}
		session.setAttribute("user_order", order);
		if (check.size() > 0) {
			req.setAttribute("check", check);
			req.getRequestDispatcher("/pages/payment1.jsp").forward(req, resp);
		} else {
			resp.sendRedirect("/dang-ky-mua-hang/hinh-thuc-thanh-toan");
		}
	}

	protected void processOrderProduct(HttpServletRequest req,
			HttpServletResponse resp, OrderModel order) {
		List<OrderProductModel> listOrderProduct = order
				.getListOrderProductObject();
		for (int i = 0; i < listOrderProduct.size(); i++) {
			int quantity = 0;
			String strQuantity = req.getParameter(listOrderProduct.get(i)
					.getProductId());
			try {
				quantity = Integer.parseInt(strQuantity);
			} catch (Exception e) {
				quantity = 0;
			}
			listOrderProduct.get(i).setQuantity(quantity);
		}
		order.setListOrderProductObject(listOrderProduct);
	}
}
